package com.walming.generator.support.controller;

import com.alibaba.druid.pool.DruidDataSource;
import com.walming.generator.common.constant.Constants;
import com.walming.generator.common.core.controller.BaseController;
import com.walming.generator.common.core.domain.AjaxResult;
import com.walming.generator.common.core.page.TableDataInfo;
import com.walming.generator.common.exception.DemoModeException;
import com.walming.generator.common.utils.DataSourceComposeUtils;
import com.walming.generator.common.utils.text.Convert;
import com.walming.generator.framework.aspectj.lang.enums.DataSourceType;
import com.walming.generator.framework.datasource.DynamicDataSourceUtil;
import com.walming.generator.support.domain.SysDataSource;
import com.walming.generator.support.query.SysDataSourceQuery;
import com.walming.generator.support.service.ISysDataSourceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.sql.Connection;
import java.util.Arrays;
import java.util.List;

/**
 * 系统数据源信息
 *
 * @author walming
 */
@Controller
@RequestMapping("/system/dataSource")
@Api(value = "系统数据源信息", tags = "系统数据源信息")
public class SysDataSourceController extends BaseController {

    private static final String PREFIX = "system/dataSource";

    @Resource
    private ISysDataSourceService dataSourceService;

    /**
     * 数据源
     */
    @GetMapping()
    public String config() {
        return PREFIX + "/list";
    }

    /**
     * 分页条件查询获取数据源信息
     *
     * @param sourceQuery 查询条件
     * @return 分页列表
     */
    @ResponseBody
    @PostMapping("/list")
    @ApiOperation(value = "分页条件查询获取数据源信息", notes = "分页条件查询获取数据源信息")
    public TableDataInfo<SysDataSource> list(SysDataSourceQuery sourceQuery) {
        return toPageResult(dataSourceService.startPage(sourceQuery));
    }

    /**
     * 选择数据源
     */
    @GetMapping("/select")
    public String selectDataSource() {
        return PREFIX + "/select";
    }

    /**
     * 数据源新增
     */
    @GetMapping("/add")
    public String add(ModelMap modelMap) {
        modelMap.put("dataSource", new SysDataSource());
        return PREFIX + "/config";
    }

    /**
     * 数据源编辑
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap modelMap) {
        SysDataSource dataSource = dataSourceService.getById(id);
        modelMap.put("dataSource", dataSource);
        return PREFIX + "/config";
    }

    /**
     * 测试连接数据源
     */
    @ResponseBody
    @PostMapping("/connect")
    @ApiOperation(value = "测试连接数据源", notes = "测试连接数据源")
    public AjaxResult<Object> connect(SysDataSource dataSource) {
        if (Constants.DEMO_TAG.equals(dataSource.getId())) {
            throw new DemoModeException();
        }
        DruidDataSource druidDataSource = DataSourceComposeUtils.composeDruidDataSource(dataSource);
        Connection connection;
        try {
            //去掉连接失败重试
            druidDataSource.setBreakAfterAcquireFailure(true);
            druidDataSource.setConnectionErrorRetryAttempts(0);
            connection = druidDataSource.getConnection(5000);
            if (connection != null) {
                connection.close();
                return success("连接成功!");
            }
            return error("连接失败！请检查连接是否有效或开放对应权限！");
        } catch (Exception e) {
            return error("连接失败！请检查连接是否有效或开放对应权限！");
        }
    }

    /**
     * 设置系统数据源（保存）
     */
    @ResponseBody
    @PostMapping("/save")
    @ApiOperation(value = "设置系统数据源（保存）", notes = "设置系统数据源（保存）")
    public AjaxResult<Object> save(SysDataSource dataSource) {
        dataSource.setStatus("0");
        // 是否是更新
        boolean result;
        boolean updateFlag = false;
        if (dataSource.getId() != null) {
            if (Constants.DEMO_TAG.equals(dataSource.getId())) {
                throw new DemoModeException();
            }
            result = dataSourceService.updateById(dataSource);
            updateFlag = true;
        } else {
            dataSource.setUpdateBy(null);
            dataSource.setUpdateTime(null);
            result = dataSourceService.save(dataSource);
        }
        if (result) {
            DruidDataSource druidDataSource = DataSourceComposeUtils.composeDruidDataSource(dataSource);
            if (updateFlag) {
                //替换数据源
                DynamicDataSourceUtil.replaceTargetDataSource(DataSourceType.SLAVE.name() + Convert.toStr(dataSource.getId()), druidDataSource);
            } else {
                //添加数据源
                DynamicDataSourceUtil.addTargetDataSource(DataSourceType.SLAVE.name() + Convert.toStr(dataSource.getId()), druidDataSource);
            }
            //刷新数据源
            DynamicDataSourceUtil.flushDataSource();
        }
        return toAjax(result);
    }

    /**
     * 根据id删除系统数据源
     *
     * @param ids 需要删除数据的id（多个用逗号分隔）
     * @return 结果
     */
    @ResponseBody
    @PostMapping("/remove")
    @ApiOperation(value = "根据id删除系统数据源", notes = "根据id删除系统数据源")
    @ApiImplicitParam(name = "ids", value = "需要删除数据的id（多个用逗号分隔）")
    public AjaxResult<Object> remove(String ids) {
        List<String> list = Arrays.asList(Convert.toStrArray(ids));
        if (list.contains(Constants.DEMO_TAG.toString())) {
            throw new DemoModeException();
        }
        boolean result = dataSourceService.removeByIds(list);
        if (result) {
            String[] array = Convert.toStrArray(ids);
            for (String id : array) {
                // 删除数据源
                DynamicDataSourceUtil.deleteTargetDataSource(DataSourceType.SLAVE.name() + id);
            }
            // 刷新数据源
            DynamicDataSourceUtil.flushDataSource();
        }
        return toAjax(result);
    }

    /**
     * 数据源状态修改
     */
    @ResponseBody
    @PostMapping("/changeStatus")
    @ApiOperation(value = "数据源状态修改", notes = "数据源状态修改")
    public AjaxResult<Object> changeStatus(SysDataSource dataSource) {
        if (Constants.DEMO_TAG.equals(dataSource.getId())) {
            throw new DemoModeException();
        }
        return toAjax(dataSourceService.updateById(dataSource));
    }

}
